
/**
 ******************************************************************************
 * @file    log.c
 * @author  MCU Team
 * @Version V1.0.0
 * @Date    2022/01/17
 * @brief   log function
 ******************************************************************************
 */


#include "zb32l03x_hal.h"
#include <stdio.h>
#include <string.h>
#include "bsp_usart.h"
#include "tty.h"
#include "log.h"


#if defined(HAL_UART_MODULE_ENABLED)
//=============================================================================
//                  Constant Definition
//=============================================================================

//=============================================================================
//                  Macro Definition
//=============================================================================
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */



/**
 *  @brief  Serial1 (UART1) Initialization Function
 *
 *  @param [in] baud_rate       The target baud rate
 *  @return
 *      None
 */
__used static void _SerialInit(uint32_t baud_rate)
{
    tty.init(115200);
    return;
}

static void _SerialOutput(char *pData)
{
    while( *pData != 0 )
    {
       tty.write((uint8_t *)pData++,1);
    }
    return;
}

__used static void _SerialSend(uint8_t data)
{
    uint8_t buff[1];
    buff[0]=data;
    tty.write(buff,1);
    return;
}

//=============================================================================
//                  Public Function Definition
//=============================================================================
/**
 *  @brief  Log module initialize
 *
 *  @return
 *      None
 */
void LogInit(void)
{
#if defined(LOG_METHOD_SERIAL) && (LOG_METHOD_SERIAL)
    _SerialInit(LOG_SERIAL_BPS);
#endif
}

void LogMemory(
    char *prefix,
    uint32_t *pAddr,
    int bytes,
    int has_out_u32le)
{
    if (has_out_u32le)
    {
        uintptr_t addr = (uintptr_t)pAddr;
        uint32_t cnt = (bytes + 0x3) >> 2;
        uint32_t *pCur = (uint32_t *)pAddr;

        for (int i = 0; i < cnt; i++)
        {
            if ((i & 0x3) == 2)
                printf(" -");
            else if (!(i & 0x3))
            {
                printf("\n%s%08X |", prefix, addr);
                addr += 16;
            }

            printf(" %08X", pCur[i]);
        }
        printf("\n\n");
    }
    else
    {
        uintptr_t addr = (uintptr_t)pAddr;
        uint8_t *pCur = (uint8_t *)pAddr;

        for (int i = 0; i < bytes; i++)
        {
            if ((i & 0xF) == 8)
                printf(" -");
            else if (!(i & 0xF))
            {
                printf("\n%s%08X |", prefix, addr);
                addr += 16;
            }

            printf(" %02X", pCur[i]);
        }
        printf("\n\n");
    }

    return;
}

PUTCHAR_PROTOTYPE
{
#if defined(LOG_METHOD_SERIAL) && (LOG_METHOD_SERIAL)
    _SerialSend(ch);
#elif defined(LOG_METHOD_SWO) && (LOG_METHOD_SWO)
    // ITM_SendChar(ch);
#elif defined(LOG_METHOD_RAM)
    *LOG_RAM_CHAR = (char)(ch & 0xFF);
#endif
    return ch;
}

void panic(const char *func)
{
    // If panic info enabled, print it out

    _SerialOutput("Panic call from ");
    _SerialOutput((char *)func);
    _SerialOutput("\n");

    /* Add any panic string desired or while loop as needed */
}
#endif  /* HAL_UART_MODULE_ENABLED */

#if defined(LOG_METHOD_RAM) && (LOG_METHOD_RAM)
static uint32_t     ___var __attribute__((at(LOG_RAM_ADDRESS)));
#endif
